package com.xiashitech.apiservice.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xiashitech.interfaces.apiservice.MockRowDataGenerator;

import lombok.var;

import java.util.*;

/**
 * @apiNote 生成伪行算法
 * @since 2023-12-06
 * @author lifuquan
 *         HybridDataGenerator采用的数据的混合的数据合成方法
 *         利用部分真实数据:结合部分真实数据，生成具有相似特征的伪行数据。
 */
public class HybridDataGenerator implements MockRowDataGenerator {
    @Override
    public JSONArray processMockRowData(int insertIndex, JSONArray data) {
        var rows = data.size();
        var cols = getCols(data);
        var isJsonArray = isJsonArray(data);
        List<String> keys = new ArrayList<>();
        if (!isJsonArray)
            keys = new ArrayList<>(data.getJSONObject(0).keySet());
        var columnIndex = 0;
        var insertedItem = createInsertedItem(isJsonArray);
        var randomNumbers = getRandomNumbers(cols, rows);
        for (var num : randomNumbers) {
            if (isJsonArray) {
                var listItem = data.getJSONArray(num);
                if (columnIndex < listItem.size()) {
                    ((JSONArray) insertedItem).add(listItem.get(columnIndex));
                }
            } else {
                var mapItem = data.getJSONObject(num);
                var key = keys.get(columnIndex);
                if (mapItem.containsKey(key)) {
                    ((JSONObject) insertedItem).put(key, mapItem.get(key));
                }
            }
            columnIndex++;
        }
        return addDummyRowsToOriginalData(data, insertIndex, insertedItem);
    }

    private JSON createInsertedItem(boolean isJsonArray) {
        return isJsonArray ? new JSONArray() : new JSONObject(true);
    }

    /**
     * 得到一随机行的集合
     */
    private List<Integer> getRandomNumbers(int cols, int rows) {
        var random = new Random();
        List<Integer> randomNumbers = new ArrayList<>();
        if (cols > rows) {
            for (int i = 0; i < cols; i++) {
                int randomNumber = random.nextInt(rows);
                randomNumbers.add(randomNumber);
            }
        } else {
            Set<Integer> uniqueRandomNumbers = new HashSet<>();
            while (uniqueRandomNumbers.size() < cols) {
                var randomNumber = random.nextInt(rows);
                uniqueRandomNumbers.add(randomNumber);
            }
            randomNumbers.addAll(uniqueRandomNumbers);
        }
        return randomNumbers;
    }

    /**
     * 插入伪行
     */
    private JSONArray addDummyRowsToOriginalData(JSONArray data, int insertIndex, JSON insertedItem) {
        var result = new JSONArray();
        var obj = data.get(0);
        if (data.size() == insertIndex){
            result.addAll(data);
            result.add(insertedItem);
            return result;
        }
        for (var i = 0; i < data.size(); i++) {
            if (i == insertIndex) {
                result.add(insertedItem);
            }
            result.add((obj instanceof Map) ? data.getJSONObject(i) : data.getJSONArray(i));
        }
        return result;
    }

    private boolean isJsonArray(JSONArray data) {
        return data.get(0) instanceof List;
    }

    /**
     * 得到列数
     */
    private int getCols(JSONArray data) {
        var obj = data.get(0);
        return (obj instanceof Map) ? data.getJSONObject(0).size() : data.getJSONArray(0).size();
    }

}
